/**
 * Author(s): xuming.Wong <xuming.Wong@gmail.com>
 */

#include "PortfolioManager.h"
#include "Utilities.h"
#include "StockDatabase.h"

namespace QSThink
{

	const QString PortfolioManager::PortfolioFileName="portfolio.data";
	

	PortfolioManager& PortfolioManager::getSingleton()
	{
		static PortfolioManager inst;
		return inst;
	}

	PortfolioManager::PortfolioManager()
	{

		loadPortfolio();


		//Set timer for we need update portfolio capital with network
		QTimer *timer = new QTimer(this);
		connect(timer, SIGNAL(timeout()), this, SLOT(update()));
		timer->start(3000);//3 seconds

	}

	void PortfolioManager::update()
	{
		if(!Utilities::exchangeOpen()){
			return;
		}

		//get all portfolio realtime info
		int cnt=_items.size();
		for(int i=0;i<cnt;++i){
			QString symbol=_items[i]->symbol;
			QueryManager::getSingleton().getRealtimeInfo(symbol);

		}

	}


	void PortfolioManager::addSymbol( QString symbol )
	{
		int cnt=_items.size();
		for(int i=0;i<cnt;++i){
			if(_items[i]->symbol==symbol){
				//just return when symbol is exist
				return;
			}
		}

		if(!StockDatabase::getSingleton().hasSymbol(symbol)){
			return;
		}
		//get current date time
		QString time=Utilities::getCurrentDateTimeString();

		QDateTime dateTime=QDateTime::currentDateTime();
		PortfolioItem* item=new PortfolioItem;
		item->symbol=symbol;

		persist();

	}

	int PortfolioManager::getSymbolCount()
	{

		return _items.size();
	}

	void PortfolioManager::addListener( PortfolioListener* listener )
	{
		_listeners.push_back(listener);
	}

	QString PortfolioManager::getSymbol( int index )
	{
		return _items[index]->symbol;//we don't check index, just crash
	}

	void PortfolioManager::removeSymbol(QString symbol )
	{
		std::vector<PortfolioItem*>::iterator it=_items.begin();
		for(;it!=_items.end();++it){
			if((*it)->symbol==symbol){
				_items.erase(it);
				break;
			}
		}


		persist();

	}

	void PortfolioManager::persist()
	{
		QFile file(PortfolioFileName);
		if (!file.open(QFile::WriteOnly)){
			return;
		}


		int cnt=_items.size();
		for(int i=0;i<cnt;i++){
			QString line=_items[i]->symbol;
			line+="\t";
			line+=Utilities::getDateTimeStr(_items[i]->dateTime);
			line+="\t";
			line+=QString::number(_items[i]->amount);
			line+="\n";

			QByteArray bytes= QTextCodec::codecForName("GB2312")->fromUnicode(line);

			file.write(bytes);
		
		}
		
		
	}

	void PortfolioManager::loadPortfolio()
	{
		QFile file(PortfolioFileName);
		if (!file.open(QFile::ReadOnly)){
			return;
		}


		while (!file.atEnd()) {
			QByteArray bytes = file.readLine();
			if (!bytes.isEmpty()){//GB2312
				QString line=QTextCodec::codecForName("GB2312")->toUnicode(bytes);
				QStringList words=line.split("\t");

				if(words.length()==3){
					QString symbol=words[0];//symbol;
					QString time=words[1];//
					int amount=words[2].toInt();

					PortfolioItem* item=new PortfolioItem;
					item->symbol=symbol;
					item->amount=amount;
					
					_items.push_back(item);

					QueryManager::getSingleton().getRealtimeInfo(symbol);

				}
			}
		}

	}

	int PortfolioManager::getAmount( int index )
	{
		return _items[index]->amount;

	}

	int PortfolioManager::getAmount( QString symbol )
	{
		int cnt=_items.size();
		for(int i=0;i<cnt;++i){
			if(_items[i]->symbol==symbol){
				return _items[i]->amount;
			}
		}

		return 0;
	}

	void PortfolioManager::setAmount( QString symbol ,int amount)
	{
		int cnt=_items.size();
		for(int i=0;i<cnt;++i){
			if(_items[i]->symbol==symbol){
				_items[i]->amount=amount;
			}
		}

		persist();
	}

	void PortfolioManager::OnTransactionReceived( DiscreteTransaction* info )
	{
		PortfolioItem* item= getPortfolioItem(info->symbol);

		if(!item){
			return;
		}
		item->price=info->price;
		item->highPrice=info->highPrice;
		item->lowPrice=info->lowPrice;
		item->openPrice=info->openPrice;
		item->lastClosePrice=info->lastClosePrice;

		int cnt=_listeners.size();
		for(int i=0;i<cnt;i++){
			_listeners[i]->OnPortfolioUpdated(item);

		}

	}

	PortfolioItem* PortfolioManager::getPortfolioItem( QString symbol )
	{
		int cnt=_items.size();
		for(int i=0;i<cnt;++i){
			if(_items[i]->symbol==symbol){
				return _items[i];
			}
		}
		return 0;

	}

	float PortfolioManager::getCapital()
	{
		float total=0;
		int cnt=_items.size();
		for(int i=0;i<cnt;++i){
			total+=_items[i]->price*_items[i]->amount;
		}
		return total;
	}

	

	PortfolioListener::PortfolioListener()
	{
		PortfolioManager::getSingleton().addListener(this);
	}


	

}
